今天要來講基本的Compose建構畫面所需要的一些方法功能,首先會先講三個主要的排版元素以及每個元素內的原件擺放位置的參數說明,接著會講Button以及點擊功能。
Compose 中的三個基本標準版面配置元素為 Column
、Row
和 Box
。
Column這個配置就如同XML中的LinearLayout的直向排列,在當中布置的元件都會佔據一個橫排來做顯示。放第二個就會下排到下一行。
如下程式碼中所示,我把function中的文字多加入了一行GreetName
參數去作為 "送出祝福者"
的身分,這邊轉寫完成後將文字填入後預覽出來就會如下圖所示。
@Composable
fun GreetingMessage(Greetingmes: String, GreetName:String, modifier: Modifier = Modifier) {
Column{
Text(
text = Greetingmes,
modifier = modifier,
)
Text(
text = GreetName,
modifier = Modifier.align(Alignment.End)
)
}
}
我們在將Column改成Row來看看結果,若剛剛有把文字調整過長則會無法顯示第二個參數所輸入的字串,這是因為文字被擠到外面去了,這時只要在添加以下程式碼中的modifier = Modifier.weight(1f)
這個功能的意思為:將分布切成1:1
的比例,依據數字的不同切成不同的比例。
Row{
Text(
text = Greetingmes,
modifier = Modifier
.weight(1f)
)
Text(
text = GreetName,
modifier = Modifier
.weight(1f)
.align(Alignment.Bottom)
)
}
Box
的功能就有點類似 ConstraintLayout
,Box是給定一個區域讓我們自己去設定位置所在,位置的鎖定會交由modifier的align去制定。
Box(
modifier = Modifier
.fillMaxWidth()
.fillMaxHeight()
){
Text(
text = Greetingmes,
modifier = Modifier.align(Alignment.TopStart)
)
Text(
text = GreetName,
modifier = Modifier.align(Alignment.BottomEnd)
)
}
這當中我將Box去做大小配置,讓他填滿畫面的長寬,接著再設定文字的位置排定。
Row使用:
Column使用:
Box使用:
有了以上排版元素的基礎概念後,這邊要加入Button按鈕來實戰點擊功能。
在Compose中提供了很多外觀樣式的質感按鈕選項供給各位選擇
ElevatedButton(onClick = {
Log.e("ElevatedButton", "GreetingMessage: " )
}) {
Text(text = "Click Me")
}
Button(onClick = {
Log.e("button", "GreetingMessage: " )
}) {
Text(text = "Click Me")
}
OutlinedIconButton(onClick = {
Log.e("OutlinedIconButton", "GreetingMessage: " )
}) {
Text(text = "Click Me")
}
OutlinedButton(onClick = {
Log.e("OutlinedButton", "GreetingMessage: " )
}) {
Text(text = "Click Me")
}
TextButton(onClick = {
Log.e("TextButton", "GreetingMessage: " )
}) {
Text(text = "Click Me")
}
FilledIconButton(onClick = {
Log.e("FilledIconButton", "GreetingMessage: " )
}) {
Text(text = "Click Me")
}
圖示預覽如下
這邊我選擇使用第一個按鈕ElevatedButton
來實作模擬顯示詳細資訊的 展開 和 關閉 功能。
remember{mutableStateIf()}
會發現按鈕個功能一直維持顯示 "詳細" 字樣,這是因為: Compose 並未追蹤這個變數,另外,每次呼叫 GreetingMessage() 的時候,這個變數都會重設為 false,所以需要加入 mutableStateOf
函式,讓 Compose 重組讀取該狀態的函式,再加入 remember
「記住」 可變動狀態,「保護」 項目不受重組影響,讓系統不會重設狀態。@Composable
fun GreetingMessage(Greetingmes: String, GreetName:String, modifier: Modifier = Modifier) {
// 如果想在重組後保留住狀態,請使用 remember「記住」可變動狀態。
val expanded = remember {mutableStateOf(false)}
val extraPadding = if (expanded.value) 24.dp else 0.dp
Column(modifier = Modifier.padding(24.dp)) {
Row(modifier = Modifier
.padding(bottom = extraPadding)
){
Text(
text = Greetingmes,
modifier = Modifier
.align(Alignment.Top)
.weight(3f)
)
Text(
text = GreetName,
modifier = Modifier
.align(Alignment.Bottom)
.weight(1f)
)
}
ElevatedButton(onClick = {
Log.e("ElevatedButton", "GreetingMessage: " )
expanded.value =! expanded.value
}) {
Text(if (expanded.value) "簡略" else "詳細")
}
}
}
以上可以看到展開後的格子會較大,這是因為我將Row的底部拓展 .padding(bottom = extraPadding)
參數設為點擊後的 expanded.value
參數更換數值 extraPadding
但是這邊還有巨大的缺點,可以看到因為是在同一個function內,所以當中的參數是共用的導致此變動是一致顯示,下面來做功能性的微調。
@Composable
fun GreetingName(
modifier: Modifier = Modifier,
names: List<String> = listOf()
) {
Column(modifier) {
for (name in names) {
GreetingMessage("Android 5G_Kotlin Jetpack Compose_IT_Home鐵人賽_15th", name)
}
}
}
@Composable
fun getImage() {
// 定義一張圖片
val image = painterResource(id = R.drawable.ic_launcher_5g_foreground)
Box{
Image(
// 在這邊將圖片設置為填滿整個畫面。
painter = image,
contentDescription = "5G",
modifier = Modifier
.fillMaxHeight()
.fillMaxWidth(),
contentScale = ContentScale.Crop
)
// 呼叫前面建立的人物陣列然後填入不同的人。
GreetingName(names = listOf("Jay", "John", "Mary"))
}
}
JetpackCompose_KotlinTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
getImage()
}
}
從預覽中就能看到大致結果如圖:
這邊我只使用中間的按鈕來做展示
以上是今天的Compose版面配置、各版面中元件的位置參數說明、以及按鈕的樣式及簡易功能說明與實作。